#pragma once

#include <prerequisites.h>
#include <maths.h>

class joint
{
public:
	joint(size_t id);
	~joint();

	void set_name(const std::string &name);
	void set_parent(joint *parent);

	void set_transforms(const matrix4 &tm);
	void set_position(const vector3 &position);
	void set_orientation(const quaternion &orientation);
	void set_scale(const vector3 &scale);

	size_t add_child(joint *child);
	void remove_child(size_t id);

	size_t get_num_childs() const;
	joint *get_child(size_t id) const;
	joint *get_parent() const;
	joint *get_root() const;
	std::string get_name() const;

	size_t get_id() const;

	vector3 get_position() const;
	quaternion get_orientation() const;
	vector3 get_scale() const;

private:
	typedef std::vector<joint*> joint_vec;

	std::string	m_name;

	joint		*m_parent;

	vector3		m_position;
	quaternion	m_orientation;
	vector3		m_scale;

	size_t		m_id;

	joint_vec	m_childs;
};

class skeleton
{
public:
	typedef std::vector<joint_ptr> joint_vec;

	skeleton();
	~skeleton();

	void set_name(const std::string &name);
	void set_animation(animation_ptr anim);

	void clear();

	joint_ptr create_joint(size_t id);

	std::string get_name() const;
	animation_ptr get_animation() const;

	size_t get_num_joints() const;
	joint_ptr get_joint_by_id(size_t id);
	joint_ptr get_joint_by_handle(size_t h);

	joint_vec build_hierarchy() const;

private:
	std::string		m_name;

	joint_vec		m_joints;

	animation_ptr	m_animation;
};